package cz.proks.simplecalendarmanager.client;

import java.util.Date;
import java.util.List;
import java.util.logging.Logger;

import cz.proks.simplecalendarmanager.client.exception.NoAccessException;
import cz.proks.simplecalendarmanager.client.exception.UserNotLoggedException;
import cz.proks.simplecalendarmanager.client.service.CalendarService;
import cz.proks.simplecalendarmanager.client.service.CalendarServiceAsync;
import cz.proks.simplecalendarmanager.client.service.OAuthService;
import cz.proks.simplecalendarmanager.client.service.OAuthServiceAsync;
import cz.proks.simplecalendarmanager.shared.ClientConstants.AppScope;
import cz.proks.simplecalendarmanager.shared.model.Calendar;
import cz.proks.simplecalendarmanager.shared.model.CalendarEvent;

import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;

import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.Tree;
import com.google.gwt.user.client.ui.VerticalPanel;

/**
 * Entry point classes define <code>onModuleLoad()</code>.
 */
public class SimpleCalendarManager implements EntryPoint {
	private static final Logger log = Logger.getLogger("SimpleCalendarManager");	
	
	private static final String SERVER_ERROR = "An error occurred while attempting to contact the server. Please check your network connection and try again.";
	private static final String DYNAMIC_DIV = "dynamicDiv";
	
	public void onModuleLoad() {
		log.info("onModuleLoad():: start");
				
		process();				
		
		log.info("onModuleLoad():: exit");
	}	
		
	private void process() {				
		log.info("process():: start");
		
		OAuthServiceAsync oauthService = GWT.create(OAuthService.class);
		AsyncCallback<Void> callback = new AsyncCallback<Void>() {

			@Override
			public void onSuccess(Void result) {
				showEvents();
			}
			
			@Override
			public void onFailure(Throwable caught) {
				try { 
					throw caught; 
				} catch (UserNotLoggedException unlex) {
					showLoginButton(unlex.getRedirectUrl());
				} catch (NoAccessException naex) {
					showGrantAccessButton(naex.getRedirectUrl());
				} catch (Throwable t) {
					// TODO: handle exception
				}				
			}						
		};
		
		oauthService.checkAccess(AppScope.CALENDAR, callback);		
		log.info("process():: exit");
	}
		
	private void showEvents() {
		log.info("showEvents():: start");
		
		CalendarServiceAsync calendarService = GWT.create(CalendarService.class);
		AsyncCallback<List<Calendar>> callback = new AsyncCallback<List<Calendar>>() {
			
			@Override
			public void onSuccess(List<Calendar> result) {
				RootPanel div = RootPanel.get(DYNAMIC_DIV);
				
				div.add(new Label("Z vašeho Google účtu byly načteny " + result.size() + " kalendáře. " +
				   				  "Dále následuje výčet každého kalendáře a událostí, které byly vytvořeny TENTO rok."));				
				div.add(new HTML("<br>"));
				
				VerticalPanel vPanel = new VerticalPanel();
				vPanel.setVisible(true);
				
				for (Calendar calendar : result) {
					vPanel.add(new Label("Pro kalendář " + calendar.getTitle() + " bylo nalezeno " + calendar.getEvents().size() + " událostí."));					
					
					Tree tree = new Tree();
					for(CalendarEvent event : calendar.getEvents()) {
						tree.addItem(new Label("Událost: " + event.getTitle()));
					}										
										
					vPanel.add(tree);
					vPanel.add(new HTML("<br>"));
				}
				
				div.add(vPanel);				
			}
			
			@Override
			public void onFailure(Throwable caught) {
				RootPanel.get(DYNAMIC_DIV).add(new Label("Failed! " + caught.getMessage()));				
			}
		}; 
		
		Date startDate = new Date();
		Date endDate = new Date();
		
		startDate.setDate(1);
		startDate.setMonth(0);
				
		calendarService.list(startDate, endDate, callback);
		
		log.info("showEvents():: exit");
	}
	
	private void showLoginButton(final String loginUrl) {
		log.info("showLoginButton():: start");
		showRedirectButton("Login", loginUrl);
		log.info("showLoginButton():: exit");
	}	
	
	private void showGrantAccessButton(final String accessUrl) {
		log.info("showGrantAccessButton():: start");
		showRedirectButton("Grant access to your calendar", accessUrl);
		log.info("showGrantAccessButton():: exit");
	}
	
	private void showRedirectButton(final String label, final String redirectUrl) {
		log.info("showRedirectButton():: start");
		
		Button loginButton = new Button(label);
		loginButton.setVisible(true);
		loginButton.addClickHandler(new ClickHandler() {
			
			@Override
			public void onClick(ClickEvent event) {
				Window.open(redirectUrl, "", "");						
			}
		});
		
		// add button		
		RootPanel.get(DYNAMIC_DIV).add(loginButton);
		log.info("showRedirectButton():: exit");
	}		
}
